package db_parameters;

require Exporter;


our @ISA = qw(Exporter);
our $VERSION = 1.00;
our @EXPORT = qw(   get_taxon_data 
					get_orthologs_protocols 
					get_orthologs_protocol_name 
					connect_to_panda
					TAXON 
					PANDA_DB_ORIGIN 
					TAX_ID 
					ID_PREFIX 
					SEQ_DIR

					PROTOCOL_NAME 
					PROTOCOL_ID 
					
					get_taxons 
					get_taxon_triplets 
					get_taxon_pairs 
					
					$db_name 
					$db_user
					$db_host 
					$dir_share_bin
					$dir_lg_share_bin 
					$dir_panda_bin 
					$dir_sequence_root

					$dir_pipeline
                    $dir_pipeline_temp 
                    $dir_pipeline_errors 
                    $dir_pipeline_ds_temp
                    log_pipeline_stage
					);



use strict;
use warnings;
use DBI;
use DBD::Pg;
use Carp;
use constant TAXON           => 0;
use constant PANDA_DB_ORIGIN => 1;
use constant TAX_ID          => 2;
use constant ID_PREFIX	     => 3;
use constant SEQ_DIR	     => 4;

use constant PROTOCOL_NAME   =>0;
use constant PROTOCOL_ID     =>1;
use FindBin;
our $db_host;
our $db_name;
our $db_user;
our $dir_lg_share_bin;
our $dir_panda_bin;
our $dir_share_bin;
our $dir_pipeline ;
our $dir_pipeline_temp ;
our $dir_pipeline_errors; 
our $dir_pipeline_ds_temp ;
our $dir_sequence_root;













BEGIN

#
#	Get parameters for entire database
#
#	These are found in the DB_PARAMETERS file in the parent directory of the running script
#
{
#	my $file_name = "$FindBin::Bin/../DB_PARAMETERS";
	use File::Spec::Functions;
#	use Module::Util qw( :all );
	my $module_dir;
	for (@INC)
	{
		if (-e $_."/db_parameters.pm")
		{
			$module_dir = $_."/";
			last;
		}
	}
	#my (undef, $module_dir,  undef) = File::Spec->splitpath(find_installed('db_parameters'));
	my $file_name = $module_dir."DB_PARAMETERS";
	
	if ($ENV{GENOME_DB_PARAM_DIR})
	{
		$file_name = $ENV{GENOME_DB_PARAM_DIR};
		$file_name =~ s/^(.*)\/?$/$1\/DB_PARAMETERS/;
	}
	open DB_PARAMETERS, $file_name or
	    die "Error\n\tCould not open $file_name\n$@";
	my %params;
	while (<DB_PARAMETERS>)
	{
		chomp;
		next unless m/^(.*?)[ \t]*=[ \t]*(.*?)[ \t]*$/;
		$params{uc $1} = $2;
	}

	$db_host				= $params{DB_HOST};
	$db_name				= $params{DB_NAME};
	$db_user				= $params{DB_USERNAME};
	$dir_lg_share_bin		= $params{DIR_SHARED_TOOLS_LG};
	$dir_panda_bin			= $params{DIR_PANDA_EXE};
	$dir_share_bin			= $params{DIR_LAB_SHARED_TOOLS};
	$dir_sequence_root		= $params{DIR_SEQUENCE_ROOT};
	$dir_pipeline			= $params{DIR_PIPELINE}; 
	$dir_pipeline_temp		= $dir_pipeline.'/pipeline_temp';
	$dir_pipeline_errors 	= $dir_pipeline.'/pipeline_errors';
	$dir_pipeline_ds_temp   = $dir_pipeline.'/pipeline_ds_temp';
}











#_________________________________________________________________________________________
#
#	log_pipeline_stage
#
#		log start and end time for specified stage of pipeline
sub log_pipeline_stage($$$$$)
{
	my ($dbh, $protocol_id, $stage, $description, $start_time) = @_;
	my $sqlcmd = "INSERT INTO genomes.analysis_log ".
			"(protocol_id, analysis_id, description, start_change, end_change) ".
			"VALUES ($protocol_id, $stage, '$description', '$start_time', CURRENT_TIMESTAMP)";
	$dbh->do($sqlcmd)		
			or croak "Failed:\n<$sqlcmd>\nDBI::errstr";
}


sub get_taxon_data()
{
	#
	#	Get DB parameters
	#

	$db_host && $db_name && $db_user
	 or croak "Error:\nDatabase parameters corrupted.\n".
			"Check for the [DB_PARAMETERS] file in the project root.\n";

	@_[1,2,3] = ($db_host, $db_name, $db_user);
	# connect to genome database
	my $dbh = DBI->connect( "dbi:Pg:dbname=$db_name;host=$db_host",
							$db_user,
							'',
							{
							  RaiseError => 1,
							  AutoCommit => 0,
							  PrintError => 1
							}
						  )
			or croak "Database connection not made: $DBI::errstr";



	my $array = $dbh->selectall_arrayref(
				"SELECT species, panda_db_origin, tax_id, id_prefix, sequence_directory ".
					"FROM genomes.taxa_parameters;")
			 or croak DBI::errstr();
	$dbh->disconnect();

	my %taxa_data;
	for my $per_taxon(@$array)
	{
		my @data = @$per_taxon;
		$taxa_data{$data[TAXON]} = [@data];
	}
	return %taxa_data;
}



#-----------------------------------------------------------------------------------------
#	Get list of orthology protocols in panda
#
#
#-----------------------------------------------------------------------------------------
sub get_orthologs_protocols()
{
	$db_host && $db_name && $db_user
	 or croak "Error:\nDatabase parameters corrupted.\n".
			"Check for the [DB_PARAMETERS] file in the project root.\n";

	# connect to genome database
	my $dbh = DBI->connect( "dbi:Pg:dbname=$db_name;host=$db_host",
							$db_user,
							'',
							{
							  RaiseError => 1,
							  AutoCommit => 0,
							  PrintError => 1
							}
						  )
			or croak "Database connection not made: $DBI::errstr";



	my $array = $dbh->selectall_arrayref(
				"SELECT name, protocol_id FROM orthologs.protocols;")
			 or croak DBI::errstr();
	$dbh->disconnect();
	croak unless @$array;
	return @$array;

}


sub get_orthologs_protocol_name($)
{
	my ($desired_protocol_id) = @_;
	for my $protocol (get_orthologs_protocols())
	{
		my ($protocol_name,  $protocol_id) = @$protocol;
		return $protocol_name if $desired_protocol_id == $protocol_id;
	}
	croak "Failed:\nNo orthology protocol name has an ID matching <$desired_protocol_id>.";
}


















#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888
#
#
#	Get taxa
#
#
#
#_________________________________________________________________________________________

#	get taxons

#_________________________________________________________________________________________
sub get_taxons(@)
{
	# get a list of all taxa
	my @taxa;
	push (@taxa, $_->[TAXON]) for (@_);
	return  sort @taxa;
}


#_________________________________________________________________________________________

#	get taxon pairs

#_________________________________________________________________________________________
sub get_taxon_pairs(@)
{
	# get a list of all taxa
	my @taxa;
	push (@taxa, $_->[TAXON]) for (@_);
	@taxa = sort @taxa;

	#
	#	generate non-duplicating taxon pairs
	#
	my @taxon_pairs;
	for (my $taxon1 = 0; $taxon1 < @taxa - 1; ++$taxon1)
	{
		for (my $taxon2 = $taxon1 + 1; $taxon2 < @taxa; ++$taxon2)
		{
			push(@taxon_pairs, [$taxa[$taxon1], $taxa[$taxon2]]);
		}
	}
	return @taxon_pairs;
}

#_________________________________________________________________________________________

#	get taxon triplets

#_________________________________________________________________________________________
sub get_taxon_triplets(\@)
{
	# get a list of all taxa
	my @taxa;
	push (@taxa, $_->[TAXON]) for (@{$_[0]});
	@taxa = sort @taxa;

	#
	#	generate non-duplicating taxon pairs
	#
	my @taxon_pairs;
	for (my $taxon1 = 0; $taxon1 < @taxa - 2; ++$taxon1)
	{
		for (my $taxon2 = $taxon1 + 1; $taxon2 < @taxa-1; ++$taxon2)
		{
			for (my $taxon3 = $taxon2 + 1; $taxon3 < @taxa; ++$taxon3)
			{
				push(@taxon_pairs, [$taxa[$taxon1], $taxa[$taxon2], $taxa[$taxon3]]);
			}
		}
	}
	return @taxon_pairs;
}
#
#
#	Get taxa
#
#
#
#88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888













#_________________________________________________________________________________________

#	Connect to panda

#_________________________________________________________________________________________
sub connect_to_panda
{
	my $dbh = DBI->connect( "dbi:Pg:dbname=$db_name;host=$db_host",
							$db_user,
							'',
							{
								RaiseError => 0,
								AutoCommit => 1,
								PrintError => 0
							}
						)
	or croak "Database connection not made: DBI::errstr()";
	return $dbh;
}







return 1;
